package org.zjt.agent.bytebuddy.binder;

import net.bytebuddy.description.annotation.AnnotationDescription;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.method.ParameterDescription;
import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.implementation.bind.MethodDelegationBinder;
import net.bytebuddy.implementation.bind.annotation.Morph;
import net.bytebuddy.implementation.bind.annotation.TargetMethodAnnotationDrivenBinder;
import net.bytebuddy.implementation.bytecode.StackManipulation;
import net.bytebuddy.implementation.bytecode.assign.Assigner;
import net.bytebuddy.implementation.bytecode.constant.TextConstant;

import java.util.Random;

/**
 * @author <a href="juntao.zhang@bkjk.com">juntao.zhang</a>
 * @Description:
 * @Package org.zjt.agent.bytebuddy.binder
 * @date 2018/2/27 15:35
 * @see
 */
public enum StringValueBinder implements TargetMethodAnnotationDrivenBinder.ParameterBinder<StringValue> {

    INSTANCE;

    @Override
    public Class<StringValue> getHandledType() {
        return StringValue.class;
    }

    @Override
    public MethodDelegationBinder.ParameterBinding<?> bind(AnnotationDescription.Loadable<StringValue> annotation,
                                                           MethodDescription source,
                                                           ParameterDescription target,
                                                           Implementation.Target implementationTarget,
                                                           Assigner assigner,
                                                           Assigner.Typing typing) {
        if (!target.getType().asErasure().represents(String.class)) {
            throw new IllegalStateException(target + " makes illegal use of @StringValue");
        }


        String content =   String.valueOf(new Random().nextInt(100));
        StackManipulation constant = new TextConstant(content);





//        new MethodDelegationBinder.ParameterBinding.Anonymous(new Morph.Binder.RedirectionProxy(forwardingMethod.getDeclaringType().asErasure(),
//                implementationTarget.getInstrumentedType(),
//                specialMethodInvocation,
//                assigner,
//                annotation.getValue(SERIALIZABLE_PROXY).resolve(Boolean.class)))


        return new MethodDelegationBinder.ParameterBinding.Anonymous(constant);
    }
}
